<?php
/**
 * forumConnect Server for xenForo (1.x)
 *
 * @category   forumConnect
 * @package    forumConnect_Server
 * @copyright  Copyright (c) 2010 Benjamin Clot (benjamin.clot@gmail.com)
 */

error_reporting(E_ALL & ~E_NOTICE);

$startTime = microtime(true);
$fileDir = dirname(__FILE__);

require($fileDir . '/library/XenForo/Autoloader.php');
XenForo_Autoloader::getInstance()->setupAutoloader($fileDir . '/library');

XenForo_Application::initialize($fileDir . '/library', $fileDir);
XenForo_Application::set('page_start_time', $startTime);

$request = new Zend_Controller_Request_Http();
$response = new Zend_Controller_Response_Http();

/**
 * XenForo_Controller_Maison
 *
 * @category   XenForo
 * @package    XenForo_Controller
 * @subpackage forumConnect
 * @copyright  Copyright (c) 2010 Benjamin Clot (benjamin.clot@gmail.com)
 */
class XenForo_Controller_forumConnect extends XenForo_Controller
{
	public function responseNoPermission()
	{
		return $this->responseError(new XenForo_Phrase('do_not_have_permission'), 403);
	}
	
	protected function _checkCsrf($action)
	{
	}
	
	protected function _handlePost($action)
	{
	}
	
	protected function _getPublicSession()
	{
		$session = new XenForo_Session();

		$session->start($this->_request->getParam('sessionid'), ip2long($this->_request->getParam('ipaddress')));
		
		if (!$session->sessionExists())
		{
			$cookiePrefix = XenForo_Application::get('config')->cookie->prefix;

			$userCookie = $this->_request->getParam('sessionuser');
			
			if ($userCookie)
			{
				$userModel = $this->getModelFromCache('XenForo_Model_User');
				
				if ($userId = $userModel->loginUserByRememberCookie($userCookie))
				{
					$session->changeUserId($userId);
				}
				else
				{
					XenForo_Helper_Cookie::deleteCookie('user', true);
				}
			}
		}

		return $session;
	}
}

/**
 * forumConnect_Server_xenForo
 *
 * @category   forumConnect
 * @package    forumConnect_Server
 * @subpackage xenForo
 * @copyright  Copyright (c) 2010 Benjamin Clot (benjamin.clot@gmail.com)
 */
final class forumConnect_Server_xenForo
{
	/**
	 * Zend_Controller_Request_Http
	 *
	 * @var	Zend_Controller_Request_Http
	 */
	protected $_request;
	
	/**
	 * Zend_Controller_Response_Http
	 *
	 * @var	Zend_Controller_Response_Http
	 */
	protected $_response;
	
	/**
	 * user cache
	 *
	 * @var	array
	 */
	protected $_usercache = array();
	
	/**
	 * XML resource handler
	 *
	 * @var	DOMDocument
	 */
	public $xml;
	
	/**
	 * Constructor
	 */
	public function __construct(Zend_Controller_Request_Http &$request, Zend_Controller_Response_Http &$response)
	{
		$this->_request = $request;
		$this->_response = $response;
		
		$this->_response->setHeader('Content-Type', 'application/xml; charset=UTF-8', true);
		$this->_response->sendResponse();		
		
		$this->xml = new DOMDocument('1.0', 'utf-8');
		$this->xml->formatOutput = true;
	}
	
	/**
	 * call - function caller
	 * 
	 * @param string
	 * @return void
	 */
	public function call($function)
	{
		if (in_array($function, array(
			'getthread',
			'getuser',
			'isloggedin'
		)))
		{
			call_user_func(array($this, '_' . $function));
		}
		else
		{
			$this->xml->createElement('error', 'This function doesn\'t exist or is not available.');
			echo $this->xml->saveXML();
			exit;
		}
	}
	
	/**
	 * _fetchuser - fetch user details
	 *
	 * @param DOMDocument|DOMElement parent node which the current node will be attached to
	 * @param	int	userid
	 * @param string username (only used if userid is null like for anonymous posts)
	 * @return void
	 */
	protected function _fetchuser(&$parentnode, $userid, $username = '')
	{
		if ($userid)
		{
			if (isset($this->_usercache[$userid]))
			{
				$user = $this->_usercache[$userid];
			}
			else
			{
				$userModel = XenForo_Model::create('XenForo_Model_User');
				$user = $userModel->getFullUserById($userid);
				
				$this->_userinfocache[$userid] = $user;
			}
		}
		
		$usernode = $this->xml->createElement('user');
		
		if (!empty($user))
		{
			$usernode->appendChild($this->xml->createElement('userid', $user['user_id']));
			$usernode->appendChild($this->xml->createElement('usergroupids', $user['user_group_id'] . ($user['secondary_group_ids'] ? $user['secondary_group_ids'] : '')));
			$usernode->appendChild($this->xml->createElement('username', $user['username']));
			$usernode->appendChild($this->xml->createElement('usertitle', $user['custom_title']));
			$usernode->appendChild($this->xml->createElement('email', $user['email']));
			
			if ($user['gravatar'])
			{
				$usernode->appendChild($this->xml->createElement('avatarurl', 'http://www.gravatar.com/avatar/' . md5($user['gravatar']) . '.jpg?s=96'));
			}
			else if (!empty($user['avatar_date']))
			{
				$usernode->appendChild($this->xml->createElement('avatarurl', XenForo_Application::$externalDataPath . '/avatars/m/' . floor($user['user_id'] / 1000) . '/' . $user['user_id'] . '.jpg?' . $user['avatar_date']));
			}
			else
			{
				$usernode->appendChild($this->xml->createElement('avatarurl', ''));
			}
			
			$usernode->appendChild($this->xml->createElement('logouthash', $user['user_id'] . ',' . XenForo_Application::$time . ',' . $user['csrf_token']));
			$usernode->appendChild($this->xml->createElement('isadmin', $user['is_admin']));
			$usernode->appendChild($this->xml->createElement('isbanned', $user['is_banned']));
			$usernode->appendChild($this->xml->createElement('isvalid', ($user['user_state'] == 'valid') ? 1 : 0));
		}
		else
		{
			$usernode->appendChild($this->xml->createElement('userid', 0));
		}
		
		$parentnode->appendChild($usernode);
	}
	
	/**
	 * _getthread - get thread details
	 * If getposts is TRUE, get the user details from the user tag inside the first post tag.
	 * If getposts is FALSE, get the user details from the user tag inside the thread tag.
	 * Posts are always returned in ascending order.
	 * 
	 * @return void
	 */
	protected function _getthread()
	{
		$getposts = (bool) $this->_request->getParam('getposts');
		$threadid = intval($this->_request->getParam('threadid'));
		
		$threadnode = $this->xml->createElement('thread');
		
		$threadModel = XenForo_Model::create('XenForo_Model_Thread');
		$thread = $threadModel->getThreadById($threadid);
		
		if (!empty($thread))
		{
			$bbCodeParser = new XenForo_BbCode_Parser(new XenForo_BbCode_Formatter_Wysiwyg);
			$bbCodeOptions = array(
				'showSignature' => false,
				'states' => array(
					'viewAttachments' => false
				)
			);
			
			$postModel = XenForo_Model::create('XenForo_Model_Post');
			$post = $postModel->getPostById($thread['first_post_id']);
			
			$threadnode->appendChild($this->xml->createElement('threadid', $thread['thread_id']));
			$threadnode->appendChild($this->xml->createElement('description', XenForo_ViewPublic_Helper_Message::getBbCodeWrapper($post, $bbCodeParser, $bbCodeOptions)));
			$threadnode->appendChild($this->xml->createElement('title', $thread['title']));
			$threadnode->appendChild($this->xml->createElement('url', XenForo_Application::get('options')->boardUrl . '/' . XenForo_Link::buildPublicLink('threads', $thread)));
			$threadnode->appendChild($this->xml->createElement('firstpostid', $thread['first_post_id']));
			$threadnode->appendChild($this->xml->createElement('lastpostid', $thread['last_post_id']));
			$threadnode->appendChild($this->xml->createElement('forumid', $thread['node_id']));
			$threadnode->appendChild($this->xml->createElement('replycount', $thread['reply_count']));
			$threadnode->appendChild($this->xml->createElement('lastusername', $thread['last_post_username']));
			$threadnode->appendChild($this->xml->createElement('lastuserid', $thread['last_post_user_id']));
			$threadnode->appendChild($this->xml->createElement('dateline', $thread['post_date']));
			$threadnode->appendChild($this->xml->createElement('views', $thread['view_count']));
			$threadnode->appendChild($this->xml->createElement('votecount', 0));
			$threadnode->appendChild($this->xml->createElement('votetotal', 0));
			$threadnode->appendChild($this->xml->createElement('isdeleted', $threadModel->isDeleted($thread)));
			$threadnode->appendChild($this->xml->createElement('isopen', $thread['discussion_open']));
			$threadnode->appendChild($this->xml->createElement('issticky', $thread['sticky']));
			$threadnode->appendChild($this->xml->createElement('isvisible', $threadModel->isVisible($thread)));
		
			if ($getposts)
			{
				$postModel = XenForo_Model::create('XenForo_Model_Post');
				$posts = $postModel->getPostsInThread($thread['thread_id']);
				
				$postsnode = $this->xml->createElement('posts');
				
				foreach ($posts as $postid => $post)
				{
					$postnode = $this->xml->createElement('post');
					
						$postnode->appendChild($this->xml->createElement('postid', $post['post_id']));
						$postnode->appendChild($this->xml->createElement('parentid', ($post['post_id'] == $thread['first_post_id'] ? '0' : $thread['first_post_id'])));
						$postnode->appendChild($this->xml->createElement('title', ''));
						$postnode->appendChild($this->xml->createElement('dateline', $post['post_date']));
						$postnode->appendChild($this->xml->createElement('content',  XenForo_ViewPublic_Helper_Message::getBbCodeWrapper($post, $bbCodeParser, $bbCodeOptions)));
						$postnode->appendChild($this->xml->createElement('url', XenForo_Application::get('options')->boardUrl . '/' . XenForo_Link::buildPublicLink('posts', $post)));
						$postnode->appendChild($this->xml->createElement('isdeleted', $postModel->isDeleted($post)));
						$postnode->appendChild($this->xml->createElement('isvisible', ($post['message_state'] == 'visible')));
						
						$this->_fetchuser($postnode, $post['user_id']);
					
					$postsnode->appendChild($postnode);
				}
				
				$threadnode->appendChild($postsnode);
			}
			else
			{
				$this->_fetchuser($threadnode, $thread['user_id']);
			}
		}
		else
		{
			$threadnode->appendChild($this->xml->createElement('threadid', 0));
		}
		
		$this->xml->appendChild($threadnode);
		
		echo $this->xml->saveXML();
		exit;
	}
	
	/**
	 * _getuser - get user details
	 * 
	 * @return void
	 */
	protected function _getuser()
	{
		$userid = intval($this->_request->getParam('userid'));
		
		$this->_fetchuser($this->xml, $userid);
		
		echo $this->xml->saveXML();
		exit;
	}
	
	/**
	 * _isloggedin - check if user is logged in
	 * NB: ipaddress comes from $_SERVER, the other variables come from the user's cookie.
	 * 
	 * @return void
	 */
	protected function _isloggedin()
	{
		$controller = new XenForo_Controller_forumConnect($this->_request, $this->_response, new XenForo_RouteMatch());
		$controller->preDispatch('');
		
		$visitor = XenForo_Visitor::getInstance();
		
		$usernode = $this->xml->createElement('user');
			$usernode->appendChild($this->xml->createElement('userid', $visitor->getUserId()));

		$this->xml->appendChild($usernode);
		
		echo $this->xml->saveXML();
		exit;
	}
}

$forumConnect_Server_xenForo = new forumConnect_Server_xenForo(&$request, &$response);
$forumConnect_Server_xenForo->call($request->getParam('do'));